import { ForbiddenException, Module } from '@nestjs/common';
import { UploadService } from './upload.service';
import { UploadController } from './upload.controller';
import { MulterModule } from '@nestjs/platform-express';
import { RedisService } from '../redis/redis.service';
import { diskStorage } from 'multer';
import * as path from 'path';
import * as fs from 'fs';


/**
 * @description: 生成文件夹路径
 * @return {*}
 */
function generateDirPath() {
  const rootPath = path.resolve(__dirname, `../../../files`);
  if (!fs.existsSync(rootPath)) {
    fs.mkdirSync(rootPath);
  }
  const date = new Date();
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  const folder = `${year}-${month}-${day}`;
  const dirPath = path.resolve(__dirname, `../../../files/${folder}`);
  if (!fs.existsSync(dirPath)) {
    fs.mkdirSync(dirPath);
  }
  return dirPath;
}

/**
 * @description: 判断是否可以上传
 * @param {RedisService} redisService
 * @return {*}
 */
async function judgeCanUpload(redisService: RedisService) {
  const today = new Date().toISOString().slice(0, 10);
  const key = `uploads:${today}`;
  let count = parseInt(await redisService.get(key));
  if (!count) {
    count = 0;
  }
  count++;
  if (count > 101) return false;
  await redisService.set(key, count);
  return count <= 100;
}

@Module({
  imports: [
    MulterModule.registerAsync({
      useFactory: (redisService: RedisService) => ({
        storage: diskStorage({
          destination: (req, file, cb) => {
            cb(null, generateDirPath())
          },
          filename: (req, file, cb) => {
            cb(null, new Date().getTime() + path.extname(file.originalname))
          }
        }),
        fileFilter: async (req, file, cb) => {
          const canUpload = await judgeCanUpload(redisService);
          if (canUpload) {
            cb(null, true);
          } else {
            cb(new ForbiddenException("今日上传次数已达上限"), false);
          }
        }
      }),
      inject: [RedisService]
    })
  ],
  controllers: [UploadController],
  providers: [UploadService],
})
export class UploadModule { }
